#######################################################
# Example of FSTDEVS Processor
# Author: moonho.hwang@gmail.com
#   Date: Oct.19.2011
#######################################################
from XSY.DEVS.Simulatable import *
from XSY.DEVS.CoupledDEVS import *
from XSY.DEVS.SimEngine import SimEngine
from XSY.DEVS.VeriEngine import VeriEngine
from XSY.Set.RandomVariables import *

class Processor(DEVS):
   def __init__(m, n, meant, parent=None):
      '''constructor'''
      DEVS.__init__(m, n, parent) 
      m.work = None
      m.meant = meant
      m.addInputPorts('?in')
      m.addOutputPorts('!out', '!out_signal')
      m.sigma = 0.0

   def delta_0(m):
      '''initial state'''
      m.phase = 'IS' # initial send 
      m.work = None
      m.sigma = 0.0

   def ta(m):
      '''time advance function'''
      return m.sigma

   def delta_ext(m, x):
      '''external transition function'''
      if x.port == m.IP['?in'] and m.phase == 'W':
         m.phase = 'S'
         m.work = x.value
         m.sigma = RV_Exponential(m.meant).sample() # random experiment from Exp(m)
      else:
         m.sigma = m.timeRemaining() # recompute the remaining time

   def _lambda(m):
      '''output function'''
      if m.phase == 'S':
         return PortValue(m.OP["!out"], m.work)
      elif m.phase == 'IS':
         return PortValue(m.OP["!out_signal"])

   def delta_int(m):
      '''internal transition function'''
      m.phase = 'W'
      m.work = None
      m.sigma = float('inf')

   def state_to_s(m):
      '''convert state to a string'''
      return "%s,%s,%.3f"%(m.phase, m.work, m.sigma)
 
def inject_f(md, JSONarg=None):
   return (md, PortValue(md.IP['?in'],'job')) 

def runSimulation(md):
   engine = SimEngine(md, inject_f)

   #---- setting StepByStep and DES simulation only ----
   engine.StepByStep = True
   engine.sfactor = float('inf')
   #----------------------------------------------------
   engine.runInteractiveMenu()

if __name__ == '__main__':
   md = Processor('Proc', 10)
   runSimulation(md) 
   print "good bye~!" 
